home *** CD-ROM | disk | FTP | other *** search
- //==================================
- // PEDUMP - Matt Pietrek 1995
- // FILE: COMMON.C
- //==================================
-
- #include <windows.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "common.h"
-
- PIMAGE_SYMBOL PCOFFSymbolTable = 0; // RVA to COFF symbol table (if present)
- DWORD COFFSymbolCount = 0; // Number of symbols in COFF symbol table
-
- typedef struct
- {
- WORD flag;
- PSTR name;
- } WORD_FLAG_DESCRIPTIONS;
-
- typedef struct
- {
- DWORD flag;
- PSTR name;
- } DWORD_FLAG_DESCRIPTIONS;
-
- // Bitfield values and names for the IMAGE_FILE_HEADER flags
- WORD_FLAG_DESCRIPTIONS ImageFileHeaderCharacteristics[] =
- {
- { IMAGE_FILE_RELOCS_STRIPPED, "RELOCS_STRIPPED" },
- { IMAGE_FILE_EXECUTABLE_IMAGE, "EXECUTABLE_IMAGE" },
- { IMAGE_FILE_LINE_NUMS_STRIPPED, "LINE_NUMS_STRIPPED" },
- { IMAGE_FILE_LOCAL_SYMS_STRIPPED, "LOCAL_SYMS_STRIPPED" },
- // { IMAGE_FILE_MINIMAL_OBJECT, "MINIMAL_OBJECT" }, // Removed in NT 3.5
- // { IMAGE_FILE_UPDATE_OBJECT, "UPDATE_OBJECT" }, // Removed in NT 3.5
- // { IMAGE_FILE_16BIT_MACHINE, "16BIT_MACHINE" }, // Removed in NT 3.5
- { IMAGE_FILE_BYTES_REVERSED_LO, "BYTES_REVERSED_LO" },
- { IMAGE_FILE_32BIT_MACHINE, "32BIT_MACHINE" },
- { IMAGE_FILE_DEBUG_STRIPPED, "DEBUG_STRIPPED" },
- // { IMAGE_FILE_PATCH, "PATCH" },
- { IMAGE_FILE_SYSTEM, "SYSTEM" },
- { IMAGE_FILE_DLL, "DLL" },
- { IMAGE_FILE_BYTES_REVERSED_HI, "BYTES_REVERSED_HI" }
- };
-
- #define NUMBER_IMAGE_HEADER_FLAGS \
- (sizeof(ImageFileHeaderCharacteristics) / sizeof(WORD_FLAG_DESCRIPTIONS))
-
- //
- // Dump the IMAGE_FILE_HEADER for a PE file or an OBJ
- //
- void DumpHeader(PIMAGE_FILE_HEADER pImageFileHeader)
- {
- UINT headerFieldWidth = 30;
- UINT i;
- char *szMachine;
-
- printf("File Header\n");
-
- switch( pImageFileHeader->Machine )
- {
- case IMAGE_FILE_MACHINE_I386: szMachine = "i386"; break;
- // case IMAGE_FILE_MACHINE_I860: szMachine = "i860"; break;
- case IMAGE_FILE_MACHINE_R3000: szMachine = "R3000"; break;
- case IMAGE_FILE_MACHINE_R4000: szMachine = "R4000"; break;
- case IMAGE_FILE_MACHINE_ALPHA: szMachine = "alpha"; break;
- default: szMachine = "unknown"; break;
- }
-
- printf(" %-*s%04X (%s)\n", headerFieldWidth, "Machine:",
- pImageFileHeader->Machine, szMachine);
- printf(" %-*s%04X\n", headerFieldWidth, "Number of Sections:",
- pImageFileHeader->NumberOfSections);
- printf(" %-*s%08X\n", headerFieldWidth, "TimeDateStamp:",
- pImageFileHeader->TimeDateStamp);
- printf(" %-*s%08X\n", headerFieldWidth, "PointerToSymbolTable:",
- pImageFileHeader->PointerToSymbolTable);
- printf(" %-*s%08X\n", headerFieldWidth, "NumberOfSymbols:",
- pImageFileHeader->NumberOfSymbols);
- printf(" %-*s%04X\n", headerFieldWidth, "SizeOfOptionalHeader:",
- pImageFileHeader->SizeOfOptionalHeader);
- printf(" %-*s%04X\n", headerFieldWidth, "Characteristics:",
- pImageFileHeader->Characteristics);
- for ( i=0; i < NUMBER_IMAGE_HEADER_FLAGS; i++ )
- {
- if ( pImageFileHeader->Characteristics &
- ImageFileHeaderCharacteristics[i].flag )
- printf( " %s\n", ImageFileHeaderCharacteristics[i].name );
- }
- }
-
- #if 0
- // Marked as obsolete in MSDN CD 9
- // Bitfield values and names for the DllCharacteritics flags
- WORD_FLAG_DESCRIPTIONS DllCharacteristics[] =
- {
- { IMAGE_LIBRARY_PROCESS_INIT, "PROCESS_INIT" },
- { IMAGE_LIBRARY_PROCESS_TERM, "PROCESS_TERM" },
- { IMAGE_LIBRARY_THREAD_INIT, "THREAD_INIT" },
- { IMAGE_LIBRARY_THREAD_TERM, "THREAD_TERM" },
- };
- #define NUMBER_DLL_CHARACTERISTICS \
- (sizeof(DllCharacteristics) / sizeof(WORD_FLAG_DESCRIPTIONS))
- #endif
-
- #if 0
- // Marked as obsolete in MSDN CD 9
- // Bitfield values and names for the LoaderFlags flags
- DWORD_FLAG_DESCRIPTIONS LoaderFlags[] =
- {
- { IMAGE_LOADER_FLAGS_BREAK_ON_LOAD, "BREAK_ON_LOAD" },
- { IMAGE_LOADER_FLAGS_DEBUG_ON_LOAD, "DEBUG_ON_LOAD" }
- };
- #define NUMBER_LOADER_FLAGS \
- (sizeof(LoaderFlags) / sizeof(DWORD_FLAG_DESCRIPTIONS))
- #endif
-
- // Names of the data directory elements that are defined
- char *ImageDirectoryNames[] = {
- "EXPORT", "IMPORT", "RESOURCE", "EXCEPTION", "SECURITY", "BASERELOC",
- "DEBUG", "COPYRIGHT", "GLOBALPTR", "TLS", "LOAD_CONFIG",
- "BOUND_IMPORT", "IAT" }; // These last two entries added for NT 3.51
-
- #define NUMBER_IMAGE_DIRECTORY_ENTRYS \
- (sizeof(ImageDirectoryNames)/sizeof(char *))
-
- //
- // Dump the IMAGE_OPTIONAL_HEADER from a PE file
- //
- void DumpOptionalHeader(PIMAGE_OPTIONAL_HEADER optionalHeader)
- {
- UINT width = 30;
- char *s;
- UINT i;
-
- printf("Optional Header\n");
-
- printf(" %-*s%04X\n", width, "Magic", optionalHeader->Magic);
- printf(" %-*s%u.%02u\n", width, "linker version",
- optionalHeader->MajorLinkerVersion,
- optionalHeader->MinorLinkerVersion);
- printf(" %-*s%X\n", width, "size of code", optionalHeader->SizeOfCode);
- printf(" %-*s%X\n", width, "size of initialized data",
- optionalHeader->SizeOfInitializedData);
- printf(" %-*s%X\n", width, "size of uninitialized data",
- optionalHeader->SizeOfUninitializedData);
- printf(" %-*s%X\n", width, "entrypoint RVA",
- optionalHeader->AddressOfEntryPoint);
- printf(" %-*s%X\n", width, "base of code", optionalHeader->BaseOfCode);
- printf(" %-*s%X\n", width, "base of data", optionalHeader->BaseOfData);
- printf(" %-*s%X\n", width, "image base", optionalHeader->ImageBase);
-
- printf(" %-*s%X\n", width, "section align",
- optionalHeader->SectionAlignment);
- printf(" %-*s%X\n", width, "file align", optionalHeader->FileAlignment);
- printf(" %-*s%u.%02u\n", width, "required OS version",
- optionalHeader->MajorOperatingSystemVersion,
- optionalHeader->MinorOperatingSystemVersion);
- printf(" %-*s%u.%02u\n", width, "image version",
- optionalHeader->MajorImageVersion,
- optionalHeader->MinorImageVersion);
- printf(" %-*s%u.%02u\n", width, "subsystem version",
- optionalHeader->MajorSubsystemVersion,
- optionalHeader->MinorSubsystemVersion);
- printf(" %-*s%X\n", width, "Reserved1", optionalHeader->Reserved1);
- printf(" %-*s%X\n", width, "size of image", optionalHeader->SizeOfImage);
- printf(" %-*s%X\n", width, "size of headers",
- optionalHeader->SizeOfHeaders);
- printf(" %-*s%X\n", width, "checksum", optionalHeader->CheckSum);
- switch( optionalHeader->Subsystem )
- {
- case IMAGE_SUBSYSTEM_NATIVE: s = "Native"; break;
- case IMAGE_SUBSYSTEM_WINDOWS_GUI: s = "Windows GUI"; break;
- case IMAGE_SUBSYSTEM_WINDOWS_CUI: s = "Windows character"; break;
- case IMAGE_SUBSYSTEM_OS2_CUI: s = "OS/2 character"; break;
- case IMAGE_SUBSYSTEM_POSIX_CUI: s = "Posix character"; break;
- default: s = "unknown";
- }
- printf(" %-*s%04X (%s)\n", width, "Subsystem",
- optionalHeader->Subsystem, s);
-
- #if 0
- // Marked as obsolete in MSDN CD 9
- printf(" %-*s%04X\n", width, "DLL flags",
- optionalHeader->DllCharacteristics);
- for ( i=0; i < NUMBER_DLL_CHARACTERISTICS; i++ )
- {
- if ( optionalHeader->DllCharacteristics &
- DllCharacteristics[i].flag )
- printf( " %s", DllCharacteristics[i].name );
- }
- if ( optionalHeader->DllCharacteristics )
- printf("\n");
- #endif
-
- printf(" %-*s%X\n", width, "stack reserve size",
- optionalHeader->SizeOfStackReserve);
- printf(" %-*s%X\n", width, "stack commit size",
- optionalHeader->SizeOfStackCommit);
- printf(" %-*s%X\n", width, "heap reserve size",
- optionalHeader->SizeOfHeapReserve);
- printf(" %-*s%X\n", width, "heap commit size",
- optionalHeader->SizeOfHeapCommit);
-
- #if 0
- // Marked as obsolete in MSDN CD 9
- printf(" %-*s%08X\n", width, "loader flags",
- optionalHeader->LoaderFlags);
-
- for ( i=0; i < NUMBER_LOADER_FLAGS; i++ )
- {
- if ( optionalHeader->LoaderFlags &
- LoaderFlags[i].flag )
- printf( " %s", LoaderFlags[i].name );
- }
- if ( optionalHeader->LoaderFlags )
- printf("\n");
- #endif
-
- printf(" %-*s%X\n", width, "RVAs & sizes",
- optionalHeader->NumberOfRvaAndSizes);
-
- printf("\nData Directory\n");
- for ( i=0; i < optionalHeader->NumberOfRvaAndSizes; i++)
- {
- printf( " %-12s rva: %08X size: %08X\n",
- (i >= NUMBER_IMAGE_DIRECTORY_ENTRYS)
- ? "unused" : ImageDirectoryNames[i],
- optionalHeader->DataDirectory[i].VirtualAddress,
- optionalHeader->DataDirectory[i].Size);
- }
- }
-
- // Bitfield values and names for the IMAGE_SECTION_HEADER flags
- DWORD_FLAG_DESCRIPTIONS SectionCharacteristics[] =
- {
- { IMAGE_SCN_CNT_CODE, "CODE" },
- { IMAGE_SCN_CNT_INITIALIZED_DATA, "INITIALIZED_DATA" },
- { IMAGE_SCN_CNT_UNINITIALIZED_DATA, "UNINITIALIZED_DATA" },
- { IMAGE_SCN_LNK_INFO, "LNK_INFO" },
- // { IMAGE_SCN_LNK_OVERLAY, "LNK_OVERLAY" },
- { IMAGE_SCN_LNK_REMOVE, "LNK_REMOVE" },
- { IMAGE_SCN_LNK_COMDAT, "LNK_COMDAT" },
- { IMAGE_SCN_MEM_DISCARDABLE, "MEM_DISCARDABLE" },
- { IMAGE_SCN_MEM_NOT_CACHED, "MEM_NOT_CACHED" },
- { IMAGE_SCN_MEM_NOT_PAGED, "MEM_NOT_PAGED" },
- { IMAGE_SCN_MEM_SHARED, "MEM_SHARED" },
- { IMAGE_SCN_MEM_EXECUTE, "MEM_EXECUTE" },
- { IMAGE_SCN_MEM_READ, "MEM_READ" },
- { IMAGE_SCN_MEM_WRITE, "MEM_WRITE" },
- };
-
- #define NUMBER_SECTION_CHARACTERISTICS \
- (sizeof(SectionCharacteristics) / sizeof(DWORD_FLAG_DESCRIPTIONS))
-
- //
- // Dump the section table from a PE file or an OBJ
- //
- void DumpSectionTable(PIMAGE_SECTION_HEADER section,
- unsigned cSections,
- BOOL IsEXE)
- {
- unsigned i, j;
-
- printf("Section Table\n");
-
- for ( i=1; i <= cSections; i++, section++ )
- {
- printf( " %02X %-8.8s %s: %08X VirtAddr: %08X\n",
- i, section->Name,
- IsEXE ? "VirtSize" : "PhysAddr",
- section->Misc.VirtualSize, section->VirtualAddress);
- printf( " raw data offs: %08X raw data size: %08X\n",
- section->PointerToRawData, section->SizeOfRawData );
- printf( " relocation offs: %08X relocations: %08X\n",
- section->PointerToRelocations, section->NumberOfRelocations );
- printf( " line # offs: %08X line #'s: %08X\n",
- section->PointerToLinenumbers, section->NumberOfLinenumbers );
- printf( " characteristics: %08X\n", section->Characteristics);
-
- printf(" ");
- for ( j=0; j < NUMBER_SECTION_CHARACTERISTICS; j++ )
- {
- if ( section->Characteristics &
- SectionCharacteristics[j].flag )
- printf( " %s", SectionCharacteristics[j].name );
- }
- printf("\n\n");
- }
- }
-
- //
- // Used by the DumpSymbolTable() routine. It purpose is to filter out
- // the non-normal section numbers and give them meaningful names.
- //
- void GetSectionName(WORD section, PSTR buffer, unsigned cbBuffer)
- {
- char tempbuffer[10];
-
- switch ( (SHORT)section )
- {
- case IMAGE_SYM_UNDEFINED: strcpy(tempbuffer, "UNDEF"); break;
- case IMAGE_SYM_ABSOLUTE: strcpy(tempbuffer, "ABS "); break;
- case IMAGE_SYM_DEBUG: strcpy(tempbuffer, "DEBUG"); break;
- default: sprintf(tempbuffer, "%-5X", section);
- }
-
- strncpy(buffer, tempbuffer, cbBuffer-1);
- }
-
- // The names of the first group of possible symbol table storage classes
- char * SzStorageClass1[] = {
- "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
- "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
- "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
- "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
- };
-
- // The names of the second group of possible symbol table storage classes
- char * SzStorageClass2[] = {
- "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
- };
-
- //
- // Given a symbol storage class value, return a descriptive ASCII string
- //
- PSTR GetSZStorageClass(BYTE storageClass)
- {
- if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
- return SzStorageClass1[storageClass];
- else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
- && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
- return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
- else
- return "???";
- }
-
- //
- // Dumps the auxillary symbol for a regular symbol. It takes a pointer
- // to the regular symbol, since the routine needs the information in
- // that record.
- //
- void DumpAuxSymbols(PIMAGE_SYMBOL pSymbolTable)
- {
- PIMAGE_AUX_SYMBOL auxSym;
-
- auxSym = (PIMAGE_AUX_SYMBOL)(pSymbolTable+1);
-
- if ( pSymbolTable->StorageClass == IMAGE_SYM_CLASS_FILE )
- printf(" * %s\n", auxSym);
- else if ( (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) )
- {
- if ( (pSymbolTable->Type & 0xF0) == (IMAGE_SYM_DTYPE_FUNCTION << 4))
- {
- printf(" * tag: %04X size: %04X Line #'s: %08X next fn: %04X\n",
- auxSym->Sym.TagIndex, auxSym->Sym.Misc.TotalSize,
- auxSym->Sym.FcnAry.Function.PointerToLinenumber,
- auxSym->Sym.FcnAry.Function.PointerToNextFunction);
- }
- }
- else if ( (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_STATIC) )
- {
- printf(
- " * Section: %04X Len: %05X Relocs: %04X LineNums: %04X\n",
- auxSym->Section.Number, auxSym->Section.Length,
- auxSym->Section.NumberOfRelocations,
- auxSym->Section.NumberOfLinenumbers);
- }
- }
-
- //
- // Given a COFF symbol table index, look up its name. This function assumes
- // that the COFFSymbolCount and PCOFFSymbolTable variables have been already
- // set up.
- //
- BOOL LookupSymbolName(DWORD index, PSTR buffer, UINT length)
- {
- PSTR stringTable;
-
- if ( index >= COFFSymbolCount )
- return FALSE;
-
- if ( PCOFFSymbolTable == 0 )
- return FALSE;
-
- if ( PCOFFSymbolTable[index].N.Name.Short != 0 )
- {
- strncpy(buffer, PCOFFSymbolTable[index].N.ShortName, min(8,length));
- buffer[8] = 0;
- }
- else
- {
- stringTable = (PSTR)&PCOFFSymbolTable[COFFSymbolCount];
- strncpy(buffer,
- stringTable + PCOFFSymbolTable[index].N.Name.Long, length);
- buffer[length-1] = 0;
- }
-
- return TRUE;
- }
-
- //
- // Dumps a COFF symbol table from an EXE or OBJ
- //
- void DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, unsigned cSymbols)
- {
- unsigned i;
- PSTR stringTable;
- char sectionName[10];
-
- printf("Symbol Table - %X entries (* = auxillary symbol)\n", cSymbols);
-
- printf(
- "Indx Name Value Section cAux Type Storage\n"
- "---- -------------------- -------- ---------- ----- ------- --------\n");
-
- // The string table apparently starts right after the symbol table
- stringTable = (PSTR)&pSymbolTable[cSymbols];
-
- for ( i=0; i < cSymbols; i++ )
- {
- printf("%04X ", i);
-
- if ( pSymbolTable->N.Name.Short != 0 )
- printf("%-20.8s", pSymbolTable->N.ShortName);
- else
- printf("%-20s", stringTable + pSymbolTable->N.Name.Long);
-
- printf(" %08X", pSymbolTable->Value);
-
- GetSectionName(pSymbolTable->SectionNumber, sectionName,
- sizeof(sectionName));
- printf(" sect:%s aux:%X type:%02X st:%s\n",
- sectionName,
- pSymbolTable->NumberOfAuxSymbols,
- pSymbolTable->Type,
- GetSZStorageClass(pSymbolTable->StorageClass) );
-
- if ( pSymbolTable->NumberOfAuxSymbols )
- DumpAuxSymbols(pSymbolTable);
-
- // Take into account any aux symbols
- i += pSymbolTable->NumberOfAuxSymbols;
- pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
- pSymbolTable++;
- }
- }
-
- //
- // Given a section name, look it up in the section table and return a
- // pointer to the start of its raw data area.
- //
- LPVOID GetSectionPtr(PSTR name, PIMAGE_NT_HEADERS pNTHeader, DWORD imageBase)
- {
- PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
- unsigned i;
-
- for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
- {
- if ( strnicmp(section->Name, name, IMAGE_SIZEOF_SHORT_NAME) == 0 )
- return (LPVOID)(section->PointerToRawData + imageBase);
- }
-
- return 0;
- }
-
- //
- // Given a section name, look it up in the section table and return a
- // pointer to its IMAGE_SECTION_HEADER
- //
- PIMAGE_SECTION_HEADER GetSectionHeader(PSTR name, PIMAGE_NT_HEADERS pNTHeader)
- {
- PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
- unsigned i;
-
- for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
- {
- if ( strnicmp(section->Name, name, IMAGE_SIZEOF_SHORT_NAME) == 0 )
- return section;
- }
-
- return 0;
- }
-
- //
- // Given an RVA, look up the section header that encloses it and return a
- // pointer to its IMAGE_SECTION_HEADER
- //
- PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva,
- PIMAGE_NT_HEADERS pNTHeader)
- {
- PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
- unsigned i;
-
- for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
- {
- // Is the RVA within this section?
- if ( (rva >= section->VirtualAddress) &&
- (rva < (section->VirtualAddress + section->Misc.VirtualSize)))
- return section;
- }
-
- return 0;
- }
-
- //
- // Do a hexadecimal dump of the raw data for all the sections. You
- // could just dump one section by adjusting the PIMAGE_SECTION_HEADER
- // and cSections parameters
- //
- void DumpRawSectionData(PIMAGE_SECTION_HEADER section,
- PVOID base,
- unsigned cSections)
- {
- unsigned i;
- char name[IMAGE_SIZEOF_SHORT_NAME + 1];
-
- printf("Section Hex Dumps\n");
-
- for ( i=1; i <= cSections; i++, section++ )
- {
- // Make a copy of the section name so that we can ensure that
- // it's null-terminated
- memcpy(name, section->Name, IMAGE_SIZEOF_SHORT_NAME);
- name[IMAGE_SIZEOF_SHORT_NAME] = 0;
-
- // Don't dump sections that don't exist in the file!
- if ( section->PointerToRawData == 0 )
- continue;
-
- printf( "section %02X (%s) size: %08X file offs: %08X\n",
- i, name, section->SizeOfRawData, section->PointerToRawData);
-
- HexDump( MakePtr(PBYTE, base, section->PointerToRawData),
- section->SizeOfRawData );
- printf("\n");
- }
- }
-
- //
- // Dump a range of line numbers from the COFF debug information
- //
- void DumpLineNumbers(PIMAGE_LINENUMBER pln, DWORD count)
- {
- char buffer[64];
- DWORD i;
-
- printf("Line Numbers\n");
-
- for (i=0; i < count; i++)
- {
- if ( pln->Linenumber == 0 ) // A symbol table index
- {
- buffer[0] = 0;
- LookupSymbolName(pln->Type.SymbolTableIndex, buffer,
- sizeof(buffer));
- printf("SymIndex: %X (%s)\n", pln->Type.SymbolTableIndex,
- buffer);
- }
- else // A regular line number
- printf(" Addr: %05X Line: %04X\n",
- pln->Type.VirtualAddress, pln->Linenumber);
- pln++;
- }
- }
-
- PIMAGE_COFF_SYMBOLS_HEADER PCOFFDebugInfo = 0;
-
- char *SzDebugFormats[] = {
- "UNKNOWN/BORLAND","COFF","CODEVIEW","FPO","MISC","EXCEPTION","FIXUP" };
-
- //
- // Dump the debug directory array
- //
- void DumpDebugDirectory(PIMAGE_DEBUG_DIRECTORY debugDir, DWORD size, DWORD base)
- {
- DWORD cDebugFormats = size / sizeof(IMAGE_DEBUG_DIRECTORY);
- PSTR szDebugFormat;
- unsigned i;
-
- if ( cDebugFormats == 0 )
- return;
-
- printf(
- "Debug Formats in File\n"
- " Type Size Address FilePtr Charactr TimeData Version\n"
- " --------------- -------- -------- -------- -------- -------- --------\n"
- );
-
- for ( i=0; i < cDebugFormats; i++ )
- {
- szDebugFormat = (debugDir->Type <= 6)
- ? SzDebugFormats[debugDir->Type] : "???";
-
- printf(" %-15s %08X %08X %08X %08X %08X %u.%02u\n",
- szDebugFormat, debugDir->SizeOfData, debugDir->AddressOfRawData,
- debugDir->PointerToRawData, debugDir->Characteristics,
- debugDir->TimeDateStamp, debugDir->MajorVersion,
- debugDir->MinorVersion);
-
- // If COFF debug info, save its address away for later. We
- // do the check for "PointerToSymbolTable" because some files
- // have bogus values for the COFF header offset.
- if ( debugDir->Type == IMAGE_DEBUG_TYPE_COFF )
- {
- PCOFFDebugInfo =
- (PIMAGE_COFF_SYMBOLS_HEADER)(base+ debugDir->PointerToRawData);
- }
-
- debugDir++;
- }
- }
-
- //
- // Dump the COFF debug information header
- //
- void DumpCOFFHeader(PIMAGE_COFF_SYMBOLS_HEADER pDbgInfo)
- {
- printf("COFF Debug Info Header\n");
- printf(" NumberOfSymbols: %08X\n", pDbgInfo->NumberOfSymbols);
- printf(" LvaToFirstSymbol: %08X\n", pDbgInfo->LvaToFirstSymbol);
- printf(" NumberOfLinenumbers: %08X\n", pDbgInfo->NumberOfLinenumbers);
- printf(" LvaToFirstLinenumber: %08X\n", pDbgInfo->LvaToFirstLinenumber);
- printf(" RvaToFirstByteOfCode: %08X\n", pDbgInfo->RvaToFirstByteOfCode);
- printf(" RvaToLastByteOfCode: %08X\n", pDbgInfo->RvaToLastByteOfCode);
- printf(" RvaToFirstByteOfData: %08X\n", pDbgInfo->RvaToFirstByteOfData);
- printf(" RvaToLastByteOfData: %08X\n", pDbgInfo->RvaToLastByteOfData);
- }
-
-
- // Number of hex values displayed per line
- #define HEX_DUMP_WIDTH 16
-
- //
- // Dump a region of memory in a hexadecimal format
- //
- void HexDump(PBYTE ptr, DWORD length)
- {
- char buffer[256];
- PSTR buffPtr, buffPtr2;
- unsigned cOutput, i;
- DWORD bytesToGo=length;
-
- while ( bytesToGo )
- {
- cOutput = bytesToGo >= HEX_DUMP_WIDTH ? HEX_DUMP_WIDTH : bytesToGo;
-
- buffPtr = buffer;
- buffPtr += sprintf(buffPtr, "%08X: ", length-bytesToGo );
- buffPtr2 = buffPtr + (HEX_DUMP_WIDTH * 3) + 1;
-
- for ( i=0; i < HEX_DUMP_WIDTH; i++ )
- {
- BYTE value = *(ptr+i);
-
- if ( i >= cOutput )
- {
- // On last line. Pad with spaces
- *buffPtr++ = ' ';
- *buffPtr++ = ' ';
- *buffPtr++ = ' ';
- }
- else
- {
- if ( value < 0x10 )
- {
- *buffPtr++ = '0';
- itoa( value, buffPtr++, 16);
- }
- else
- {
- itoa( value, buffPtr, 16);
- buffPtr+=2;
- }
-
- *buffPtr++ = ' ';
- *buffPtr2++ = isprint(value) ? value : '.';
- }
-
- // Put an extra space between the 1st and 2nd half of the bytes
- // on each line.
- if ( i == (HEX_DUMP_WIDTH/2)-1 )
- *buffPtr++ = ' ';
- }
-
- *buffPtr2 = 0; // Null terminate it.
- puts(buffer); // Can't use printf(), since there may be a '%'
- // in the string.
- bytesToGo -= cOutput;
- ptr += HEX_DUMP_WIDTH;
- }
- }
-